package cmd

import (
	"fmt"
	"lnzw/engine/args"
	"lnzw/engine/log"
	"strings"
	"sync"

	"go.uber.org/zap"
)

type CmdId string

// cmd命令接口
type ICmd interface {
	Id() CmdId
	Run(args *args.Args) error
	Desc() string
}

var cmds = map[CmdId]ICmd{}
var once sync.Once

func Setup() {
	once.Do(func() {
		go run()
	})
}

func run() {
	defer func() {
		if err := recover(); err != nil {
			log.Logger.Error("cmd run error", zap.Any("err", err))
		}
	}()
	for {
		fmt.Printf("cmd->")
		var cmdStr string
		fmt.Scanln(&cmdStr)
		if cmdStr == "" || strings.Trim(cmdStr, " ") == "" {
			fmt.Println("cmd is empty")
			continue
		}
		params := strings.Split(cmdStr, " ")
		if len(params) == 0 {
			fmt.Println("cmd is empty")
			continue
		}

		cmdId := CmdId(params[0])
		cmd, ok := cmds[cmdId]
		if !ok {
			fmt.Println("cmd is not exist")
			continue
		}
		var arg *args.Args = nil
		if len(params) == 1 {
			arg = args.NewEmpty()
		} else {
			arg1, err := args.ValueOf(params[1:])
			if err != nil {
				fmt.Println(err)
				continue
			}
			arg = arg1
		}
		err := cmd.Run(arg)
		if err != nil {
			fmt.Println(err)
			continue
		}
	}
}

func Register(cmd ICmd) {
	cmds[cmd.Id()] = cmd
}
